import { Component } from '@angular/core';
import { FormBuilder, FormControl, Validators } from '@angular/forms';
import { FormBottonsConfigService, ThemeService } from '../../services';
import { EditState } from '../../core';
import { IdentityUserDto } from '../proxy/identity';
import { RefSelectUserService } from '../ref-select-user/ref-select-user.service';
import { IdentityUserDetailService } from './user-detail.service';
import { EntityDetailComponent } from '../../core';
import snq from 'snq';
import { RefPermissionService } from '../ref-permission/ref-permission.service';

@Component({
  selector: 'app-user-detail',
  templateUrl: './user-detail.component.html',
  styleUrls: ['./user-detail.component.less'],
  providers: [FormBottonsConfigService],
})
export class UserDetailComponent extends EntityDetailComponent<IdentityUserDto> {
  public refSelectModels(): Promise<IdentityUserDto[]> {
    return this.refSelectUserService.show().toPromise();
  }

  public get roleNames() {
    return snq(() => this.stateService.roles.filter(x => x.checked).map(x => x.label));
  }

  public get showPasswordInput() {
    return (
      this.stateService.state == EditState.Empty || this.stateService.state == EditState.Creating
    );
  }

  permissionButton = {
    name: '权限',
    fn: () => {
      if (!!this.stateService.currentModel.id) {
        this.editPermission(this.stateService.currentModel);
      }
    },
    visable: true,
    enabled: false,
    setEnabled: () => {
      switch (this.buttonConfigService.editState) {
        case EditState.Empty:
        case EditState.Creating:
          this.permissionButton.enabled = false;
          break;
        case EditState.View:
        case EditState.Editing:
        case EditState.Appoving:
        case EditState.Appoved:
          this.permissionButton.enabled = true;
          break;
      }
    },
  };

  constructor(
    public fb: FormBuilder,
    public buttonConfigService: FormBottonsConfigService,
    public stateService: IdentityUserDetailService,
    public theme: ThemeService,
    protected refSelectUserService: RefSelectUserService,
    public refPermissionService: RefPermissionService
  ) {
    super(fb, buttonConfigService, stateService);
  }

  public initValidateForm() {
    this.validateForm = this.fb.group({
      userName: [null, [Validators.required]],
      name: [null, [Validators.required]],
      email: [null, [Validators.required, Validators.email]],
      phoneNumber: [null],
      isActive: [null],
      lockoutEnabled: [false],
    });

    this.addPasswordControl();
    this.stateService.initRoles();

    this.validateForm.valueChanges.subscribe(data => this.onFormValueChanged(data));
    this.stateService.onRoleNamesChanged.subscribe(roleNames => this.setRoleValues(roleNames));

    this.buttonConfigService.approveButtonGroup.visable = false;
    this.buttonConfigService.outputButtonGroup.visable = false;

    this.buttonConfigService.buttonsConfig.push({
      buttonGroup: [this.permissionButton],
      visable: true,
    });
  }

  public copyToCreating() {
    var copyRoleNames = this.stateService.roleNames;
    this.stateService.copyToCreating().then(model => {
      this.setFormValue({ ...model, userName: '' }, true, copyRoleNames);
    });
  }

  public delete() {
    this.stateService.delete().then(() => this.resetFormValue(this.stateService.roleNames));
  }

  public select() {
    this.refSelectModels().then(models => {
      if (!!models?.length) {
        this.stateService.changeToView(models[0]['id']);
        this.stateService.setCurrentUserRoleNames(models[0].id);
      }
    });
  }

  public search() {
    if (!this.searchText) return;
    this.stateService
      .search(this.searchText)
      .then(model => {
        this.stateService.changeToView(model['id']);
        this.stateService.setCurrentUserRoleNames(model['id']);
      })
      .catch(() => {});
  }

  public submitForm() {
    this.stateService.controlValidate(!this.validateForm.valid);

    if (this.stateService.state == EditState.Creating) {
      this.stateService.save({
        ...this.validateForm.value,
        lockoutEnabled: !!this.validateForm.value?.lockoutEnabled,
        roleNames: this.roleNames,
      });
    } else if (this.stateService.state == EditState.Editing) {
      this.stateService.edit({
        ...this.stateService.currentModel,
        ...this.validateForm.value,
        lockoutEnabled: !!this.validateForm.value?.lockoutEnabled,
        id: this.stateService.currentModel.id,
        roleNames: this.roleNames,
      });
    }
  }

  public resetFormValue(roleNames?: string[]) {
    this.validateForm?.reset({}, { emitEvent: false });
    this.addPasswordControl();
    this.updateFormValidity();

    if (!!roleNames) this.setRoleValues(roleNames);
  }

  public setFormValue(
    model: IdentityUserDto,
    needPassWordControl: boolean = false,
    roleNames?: string[]
  ) {
    this.validateForm.patchValue(model, { emitEvent: false });
    if (!needPassWordControl) {
      this.removePasswordControl();
    } else {
      this.addPasswordControl();
    }
    this.updateFormValidity();

    if (!!roleNames) this.setRoleValues(roleNames);
  }

  public setRoleValues(roleNames: string[]) {
    if (!this.stateService.roles) return;

    for (var role of this.stateService.roles) {
      var checked = snq(() => roleNames.indexOf(role.label) != -1);
      if (role.checked != checked) role.checked = checked;
    }
  }

  public onSelectedRolesChanged(value: string[]): void {
    if (
      this.stateService.state == EditState.Empty &&
      !this.stateService.roleNamesEquals(this.roleNames)
    ) {
      this.stateService.changeToCreating();
    } else if (
      this.stateService.state == EditState.View &&
      !this.stateService.roleNamesEquals(this.roleNames)
    ) {
      this.stateService.changeToEditing();
    }
  }

  public editPermission(model: IdentityUserDto, event?: Event) {
    event?.stopPropagation();
    this.refPermissionService.show({ providerName: 'U', keyModel: model }).subscribe();
  }

  private addPasswordControl() {
    if (!this.validateForm.controls['password']) {
      this.validateForm.addControl(
        'password',
        new FormControl(null, [Validators.required, Validators.minLength(6)])
      );
    }
  }

  private removePasswordControl() {
    if (!!this.validateForm.controls['password']) {
      this.validateForm.removeControl('password');
    }
  }
}
